{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "9102f18f-4193-43e1-a206-50f302c5473a",
   "metadata": {},
   "outputs": [],
   "source": [
    "import re\n",
    "re.sub()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "bc6afa9c-f5a9-46f8-935f-644c31c7bd8d",
   "metadata": {
    "collapsed": true,
    "jupyter": {
     "outputs_hidden": true
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "## 图像基本操作\n",
      "\n",
      "\n",
      "\n",
      "#### 环境配置地址：\n",
      "\n",
      "\n",
      "\n",
      "- Anaconda:https://www.anaconda.com/download/\n",
      "\n",
      "\n",
      "\n",
      "- Python_whl:https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv\n",
      "\n",
      "\n",
      "\n",
      "- eclipse:按照自己的喜好，选择一个能debug就好\n",
      "\n",
      "\n",
      "\n",
      "![title](images/lena_img.png)\n",
      "\n",
      "\n",
      "\n",
      "### 数据读取-图像\n",
      "\n",
      "\n",
      "\n",
      "- cv2.IMREAD_COLOR：彩色图像\n",
      "\n",
      "- cv2.IMREAD_GRAYSCALE：灰度图像\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "import cv2 #opencv读取的格式是BGR\n",
      "\n",
      "import matplotlib.pyplot as plt\n",
      "\n",
      "import numpy as np \n",
      "\n",
      "%matplotlib inline \n",
      "\n",
      "\n",
      "\n",
      "img=cv2.imread('images/cat.jpg')\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    array([[[142, 151, 160],\n",
      "\n",
      "            [146, 155, 164],\n",
      "\n",
      "            [151, 160, 170],\n",
      "\n",
      "            ...,\n",
      "\n",
      "            [156, 172, 185],\n",
      "\n",
      "            [155, 171, 184],\n",
      "\n",
      "            [154, 170, 183]],\n",
      "\n",
      "    \n",
      "\n",
      "           [[108, 117, 126],\n",
      "\n",
      "            [112, 123, 131],\n",
      "\n",
      "            [118, 127, 137],\n",
      "\n",
      "            ...,\n",
      "\n",
      "            [155, 171, 184],\n",
      "\n",
      "            [154, 170, 183],\n",
      "\n",
      "            [153, 169, 182]],\n",
      "\n",
      "    \n",
      "\n",
      "           [[108, 119, 127],\n",
      "\n",
      "            [110, 123, 131],\n",
      "\n",
      "            [118, 128, 138],\n",
      "\n",
      "            ...,\n",
      "\n",
      "            [156, 169, 183],\n",
      "\n",
      "            [155, 168, 182],\n",
      "\n",
      "            [154, 167, 181]],\n",
      "\n",
      "    \n",
      "\n",
      "           ...,\n",
      "\n",
      "    \n",
      "\n",
      "           [[162, 186, 198],\n",
      "\n",
      "            [157, 181, 193],\n",
      "\n",
      "            [142, 166, 178],\n",
      "\n",
      "            ...,\n",
      "\n",
      "            [181, 204, 206],\n",
      "\n",
      "            [170, 193, 195],\n",
      "\n",
      "            [149, 172, 174]],\n",
      "\n",
      "    \n",
      "\n",
      "           [[140, 164, 176],\n",
      "\n",
      "            [147, 171, 183],\n",
      "\n",
      "            [139, 163, 175],\n",
      "\n",
      "            ...,\n",
      "\n",
      "            [169, 187, 188],\n",
      "\n",
      "            [125, 143, 144],\n",
      "\n",
      "            [106, 124, 125]],\n",
      "\n",
      "    \n",
      "\n",
      "           [[154, 178, 190],\n",
      "\n",
      "            [154, 178, 190],\n",
      "\n",
      "            [121, 145, 157],\n",
      "\n",
      "            ...,\n",
      "\n",
      "            [183, 198, 200],\n",
      "\n",
      "            [128, 143, 145],\n",
      "\n",
      "            [127, 142, 144]]], dtype=uint8)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "#图像的显示,也可以创建多个窗口\n",
      "\n",
      "cv2.imshow('image',img) \n",
      "\n",
      "# 等待时间，毫秒级，0表示任意键终止\n",
      "\n",
      "cv2.waitKey(0) \n",
      "\n",
      "cv2.destroyAllWindows()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "def cv_show(name,img):\n",
      "\n",
      "    cv2.imshow(name,img) \n",
      "\n",
      "    cv2.waitKey(0) \n",
      "\n",
      "    cv2.destroyAllWindows()\n",
      "\n",
      "\n",
      "\n",
      "def plt_show(img):\n",
      "\n",
      "    # opencv读取的是BGR格式 plt展示的是RGB格式 因此需要进行通道的转换\n",
      "\n",
      "    img=img[:,:,[2,1,0]]\n",
      "\n",
      "    plt.imshow(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "plt_show(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_9_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (414, 500, 3)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img=cv2.imread('images/cat.jpg',cv2.IMREAD_GRAYSCALE) #读取灰度图\n",
      "\n",
      "img\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    array([[153, 157, 162, ..., 174, 173, 172],\n",
      "\n",
      "           [119, 124, 129, ..., 173, 172, 171],\n",
      "\n",
      "           [120, 124, 130, ..., 172, 171, 170],\n",
      "\n",
      "           ...,\n",
      "\n",
      "           [187, 182, 167, ..., 202, 191, 170],\n",
      "\n",
      "           [165, 172, 164, ..., 185, 141, 122],\n",
      "\n",
      "           [179, 179, 146, ..., 197, 142, 141]], dtype=uint8)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (414, 500)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "#保存\n",
      "\n",
      "cv2.imwrite('images/mycat.png',img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    True\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "type(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    numpy.ndarray\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img.size\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    207000\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img.dtype\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    dtype('uint8')\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 数据读取-视频\n",
      "\n",
      "\n",
      "\n",
      "- cv2.VideoCapture可以捕获摄像头，用数字来控制不同的设备，例如0,1。\n",
      "\n",
      "- 如果是视频文件，直接指定好路径即可。\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "vc = cv2.VideoCapture('images/test.mp4')\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 检查是否打开正确\n",
      "\n",
      "if vc.isOpened(): \n",
      "\n",
      "    open, frame = vc.read()  #每次读取一帧\n",
      "\n",
      "else:\n",
      "\n",
      "    open = False\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "while open:\n",
      "\n",
      "    ret, frame = vc.read()\n",
      "\n",
      "    if frame is None:\n",
      "\n",
      "        break\n",
      "\n",
      "    if ret == True:\n",
      "\n",
      "        gray = cv2.cvtColor(frame,  cv2.COLOR_BGR2GRAY) #转换成灰度图\n",
      "\n",
      "        cv2.imshow('result', gray)\n",
      "\n",
      "        if cv2.waitKey(100) & 0xFF == 27:\n",
      "\n",
      "            break\n",
      "\n",
      "vc.release()\n",
      "\n",
      "cv2.destroyAllWindows()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "### 截取部分图像数据\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img=cv2.imread('images/cat.jpg')\n",
      "\n",
      "cat=img[0:50,0:200] \n",
      "\n",
      "plt_show(cat)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_23_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 颜色通道提取\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "b,g,r=cv2.split(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "r\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    array([[160, 164, 170, ..., 185, 184, 183],\n",
      "\n",
      "           [126, 131, 137, ..., 184, 183, 182],\n",
      "\n",
      "           [127, 131, 138, ..., 183, 182, 181],\n",
      "\n",
      "           ...,\n",
      "\n",
      "           [198, 193, 178, ..., 206, 195, 174],\n",
      "\n",
      "           [176, 183, 175, ..., 188, 144, 125],\n",
      "\n",
      "           [190, 190, 157, ..., 200, 145, 144]], dtype=uint8)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "r.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (414, 500)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img=cv2.merge((b,g,r))\n",
      "\n",
      "img.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (414, 500, 3)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 只保留R\n",
      "\n",
      "cur_img = img.copy()\n",
      "\n",
      "cur_img[:,:,0] = 0\n",
      "\n",
      "cur_img[:,:,1] = 0\n",
      "\n",
      "plt_show(cur_img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_29_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 只保留G\n",
      "\n",
      "cur_img = img.copy()\n",
      "\n",
      "cur_img[:,:,0] = 0\n",
      "\n",
      "cur_img[:,:,2] = 0\n",
      "\n",
      "plt_show(cur_img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_30_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 只保留B\n",
      "\n",
      "cur_img = img.copy()\n",
      "\n",
      "cur_img[:,:,1] = 0\n",
      "\n",
      "cur_img[:,:,2] = 0\n",
      "\n",
      "plt_show(cur_img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_31_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 边界填充\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "top_size,bottom_size,left_size,right_size = (50,50,50,50)  #上下左右\n",
      "\n",
      "\n",
      "\n",
      "replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)\n",
      "\n",
      "reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_REFLECT)\n",
      "\n",
      "reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT_101)\n",
      "\n",
      "wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_WRAP)\n",
      "\n",
      "constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_CONSTANT, value=0)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "import matplotlib.pyplot as plt\n",
      "\n",
      "plt.subplot(231), plt.imshow(img, 'gray'), plt.title('ORIGINAL')\n",
      "\n",
      "plt.subplot(232), plt.imshow(replicate, 'gray'), plt.title('REPLICATE')\n",
      "\n",
      "plt.subplot(233), plt.imshow(reflect, 'gray'), plt.title('REFLECT')\n",
      "\n",
      "plt.subplot(234), plt.imshow(reflect101, 'gray'), plt.title('REFLECT_101')\n",
      "\n",
      "plt.subplot(235), plt.imshow(wrap, 'gray'), plt.title('WRAP')\n",
      "\n",
      "plt.subplot(236), plt.imshow(constant, 'gray'), plt.title('CONSTANT')\n",
      "\n",
      "\n",
      "\n",
      "plt.show()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_34_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "- BORDER_REPLICATE：复制法，也就是复制最边缘像素。\n",
      "\n",
      "- BORDER_REFLECT：反射法，对感兴趣的图像中的像素在两边进行复制例如：fedcba|abcdefgh|hgfedcb   \n",
      "\n",
      "- BORDER_REFLECT_101：反射法，也就是以最边缘像素为轴，对称，gfedcb|abcdefgh|gfedcba\n",
      "\n",
      "- BORDER_WRAP：外包装法cdefgh|abcdefgh|abcdefg  \n",
      "\n",
      "- BORDER_CONSTANT：常量法，常数值填充。\n",
      "\n",
      "\n",
      "\n",
      "### 数值计算\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img_cat=cv2.imread('images/cat.jpg')\n",
      "\n",
      "img_dog=cv2.imread('images/dog.jpg')\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img_cat2= img_cat +10 \n",
      "\n",
      "img_cat[:5,:,0]\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    array([[142, 146, 151, ..., 156, 155, 154],\n",
      "\n",
      "           [108, 112, 118, ..., 155, 154, 153],\n",
      "\n",
      "           [108, 110, 118, ..., 156, 155, 154],\n",
      "\n",
      "           [139, 141, 148, ..., 156, 155, 154],\n",
      "\n",
      "           [153, 156, 163, ..., 160, 159, 158]], dtype=uint8)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img_cat2[:5,:,0]\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    array([[152, 156, 161, ..., 166, 165, 164],\n",
      "\n",
      "           [118, 122, 128, ..., 165, 164, 163],\n",
      "\n",
      "           [118, 120, 128, ..., 166, 165, 164],\n",
      "\n",
      "           [149, 151, 158, ..., 166, 165, 164],\n",
      "\n",
      "           [163, 166, 173, ..., 170, 169, 168]], dtype=uint8)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "#相当于% 256\n",
      "\n",
      "(img_cat + img_cat2)[:5,:,0] \n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    array([[ 38,  46,  56, ...,  66,  64,  62],\n",
      "\n",
      "           [226, 234, 246, ...,  64,  62,  60],\n",
      "\n",
      "           [226, 230, 246, ...,  66,  64,  62],\n",
      "\n",
      "           [ 32,  36,  50, ...,  66,  64,  62],\n",
      "\n",
      "           [ 60,  66,  80, ...,  74,  72,  70]], dtype=uint8)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "cv2.add(img_cat,img_cat2)[:5,:,0]\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    array([[255, 255, 255, ..., 255, 255, 255],\n",
      "\n",
      "           [226, 234, 246, ..., 255, 255, 255],\n",
      "\n",
      "           [226, 230, 246, ..., 255, 255, 255],\n",
      "\n",
      "           [255, 255, 255, ..., 255, 255, 255],\n",
      "\n",
      "           [255, 255, 255, ..., 255, 255, 255]], dtype=uint8)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 图像融合\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 尺寸不同不能相加\n",
      "\n",
      "# img_cat + img_dog\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img_cat.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (414, 500, 3)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img_dog = cv2.resize(img_dog, (500, 414))\n",
      "\n",
      "img_dog.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (414, 500, 3)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "res = cv2.addWeighted(img_cat, 0.4, img_dog, 0.6, 0)  #图像融合 ax+by+c\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_47_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "res = cv2.resize(img, (0, 0), fx=4, fy=4)  #按比例缩放\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_48_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "res = cv2.resize(img, (0, 0), fx=1, fy=3)\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_49_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 灰度图\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "import cv2 #opencv读取的格式是BGR\n",
      "\n",
      "import numpy as np\n",
      "\n",
      "import matplotlib.pyplot as plt #Matplotlib是RGB\n",
      "\n",
      "%matplotlib inline \n",
      "\n",
      "\n",
      "\n",
      "img=cv2.imread('images/cat.jpg')\n",
      "\n",
      "img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\n",
      "\n",
      "img_gray.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (414, 500)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "def plt_show(img):\n",
      "\n",
      "    # opencv读取的是BGR格式 plt展示的是RGB格式 因此需要进行通道的转换\n",
      "\n",
      "    img=img[:,:,[2,1,0]]\n",
      "\n",
      "    plt.imshow(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "cv2.imshow('img_gray',img_gray) \n",
      "\n",
      "cv2.waitKey(0) \n",
      "\n",
      "cv2.destroyAllWindows()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "plt.imshow(img_gray,cmap='gray')\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x110598d3520>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_54_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### HSV\n",
      "\n",
      "- H - 色调（主波长）。 \n",
      "\n",
      "- S - 饱和度（纯度/颜色的阴影）。 \n",
      "\n",
      "- V值（强度）\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)\n",
      "\n",
      "plt_show(hsv)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_56_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 图像阈值\n",
      "\n",
      "\n",
      "\n",
      "#### ret, dst = cv2.threshold(src, thresh, maxval, type)\n",
      "\n",
      "\n",
      "\n",
      "- src： 输入图，只能输入单通道图像，通常来说为灰度图\n",
      "\n",
      "- dst： 输出图\n",
      "\n",
      "- thresh： 阈值\n",
      "\n",
      "- maxval： 当像素值超过了阈值（或者小于阈值，根据type来决定），所赋予的值\n",
      "\n",
      "- type：二值化操作的类型，包含以下5种类型： cv2.THRESH_BINARY； cv2.THRESH_BINARY_INV； cv2.THRESH_TRUNC； cv2.THRESH_TOZERO；cv2.THRESH_TOZERO_INV\n",
      "\n",
      "\n",
      "\n",
      "- cv2.THRESH_BINARY           超过阈值部分取maxval（最大值），否则取0\n",
      "\n",
      "- cv2.THRESH_BINARY_INV    THRESH_BINARY的反转\n",
      "\n",
      "- cv2.THRESH_TRUNC            大于阈值部分设为阈值，否则不变\n",
      "\n",
      "- cv2.THRESH_TOZERO          大于阈值部分不改变，否则设为0\n",
      "\n",
      "- cv2.THRESH_TOZERO_INV  THRESH_TOZERO的反转\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)\n",
      "\n",
      "ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)\n",
      "\n",
      "ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)\n",
      "\n",
      "ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)\n",
      "\n",
      "ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)\n",
      "\n",
      "\n",
      "\n",
      "titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']\n",
      "\n",
      "images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]\n",
      "\n",
      "\n",
      "\n",
      "for i in range(6):\n",
      "\n",
      "    plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')\n",
      "\n",
      "    plt.title(titles[i])\n",
      "\n",
      "    plt.xticks([]), plt.yticks([])\n",
      "\n",
      "plt.show()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_58_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 图像平滑\n",
      "\n",
      "\n",
      "\n",
      "![images/image.png](attachment:image.png)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images/lenaNoise.png')\n",
      "\n",
      "plt_show(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_61_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 均值滤波\n",
      "\n",
      "# 简单的平均卷积操作\n",
      "\n",
      "blur = cv2.blur(img, (3, 3))\n",
      "\n",
      "plt_show(blur)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_62_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 方框滤波\n",
      "\n",
      "# 基本和均值一样，可以选择归一化\n",
      "\n",
      "box = cv2.boxFilter(img,-1,(3,3), normalize=True)  \n",
      "\n",
      "plt_show(box)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_63_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 方框滤波\n",
      "\n",
      "# 基本和均值一样，可以选择归一化,容易越界\n",
      "\n",
      "box = cv2.boxFilter(img,-1,(3,3), normalize=False)  \n",
      "\n",
      "plt_show(box)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_64_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 高斯滤波\n",
      "\n",
      "# 高斯模糊的卷积核里的数值是满足高斯分布，相当于更重视中间的\n",
      "\n",
      "aussian = cv2.GaussianBlur(img, (5, 5), 1)  \n",
      "\n",
      "plt_show(aussian)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_65_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 中值滤波\n",
      "\n",
      "# 相当于用中值代替\n",
      "\n",
      "median = cv2.medianBlur(img, 5)  # 中值滤波\n",
      "\n",
      "plt_show(median)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_66_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 展示所有的\n",
      "\n",
      "res = np.hstack((blur,aussian,median))\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_67_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 形态学-腐蚀操作\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images/dige.png')\n",
      "\n",
      "plt_show(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_69_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "kernel = np.ones((3,3),np.uint8) \n",
      "\n",
      "erosion = cv2.erode(img,kernel,iterations = 1)\n",
      "\n",
      "plt_show(erosion)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_70_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "pie = cv2.imread('images/pie.png')\n",
      "\n",
      "plt_show(pie)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_71_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "kernel = np.ones((30,30),np.uint8) \n",
      "\n",
      "erosion_1 = cv2.erode(pie,kernel,iterations = 1)\n",
      "\n",
      "erosion_2 = cv2.erode(pie,kernel,iterations = 2)\n",
      "\n",
      "erosion_3 = cv2.erode(pie,kernel,iterations = 3)\n",
      "\n",
      "res = np.hstack((erosion_1,erosion_2,erosion_3))\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_72_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 形态学-膨胀操作\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images/dige.png')\n",
      "\n",
      "plt_show(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_74_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "#### 先做腐蚀操作\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "kernel = np.ones((3,3),np.uint8) \n",
      "\n",
      "dige_erosion = cv2.erode(img,kernel,iterations = 1)\n",
      "\n",
      "plt_show(dige_erosion)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_76_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "#### 再做膨胀操作\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "kernel = np.ones((3,3),np.uint8) \n",
      "\n",
      "dige_dilate = cv2.dilate(dige_erosion,kernel,iterations = 1)\n",
      "\n",
      "plt_show(dige_dilate)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_78_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "pie = cv2.imread('images/pie.png')\n",
      "\n",
      "\n",
      "\n",
      "kernel = np.ones((30,30),np.uint8) \n",
      "\n",
      "dilate_1 = cv2.dilate(pie,kernel,iterations = 1)\n",
      "\n",
      "dilate_2 = cv2.dilate(pie,kernel,iterations = 2)\n",
      "\n",
      "dilate_3 = cv2.dilate(pie,kernel,iterations = 3)\n",
      "\n",
      "res = np.hstack((dilate_1,dilate_2,dilate_3))\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_79_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 开运算与闭运算\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 开：先腐蚀，再膨胀\n",
      "\n",
      "img = cv2.imread('images/dige.png')\n",
      "\n",
      "kernel = np.ones((5,5),np.uint8) \n",
      "\n",
      "opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)\n",
      "\n",
      "\n",
      "\n",
      "plt_show(opening)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_81_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 闭：先膨胀，再腐蚀\n",
      "\n",
      "img = cv2.imread('images/dige.png')\n",
      "\n",
      "kernel = np.ones((5,5),np.uint8)\n",
      "\n",
      "closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)\n",
      "\n",
      "plt_show(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_82_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 梯度运算\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 梯度=膨胀-腐蚀\n",
      "\n",
      "pie = cv2.imread('images/pie.png')\n",
      "\n",
      "kernel = np.ones((7,7),np.uint8) \n",
      "\n",
      "dilate = cv2.dilate(pie,kernel,iterations = 5)\n",
      "\n",
      "erosion = cv2.erode(pie,kernel,iterations = 5)\n",
      "\n",
      "\n",
      "\n",
      "res = np.hstack((dilate,erosion))\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_84_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernel)\n",
      "\n",
      "plt_show(gradient)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_85_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 礼帽与黑帽\n",
      "\n",
      "- 礼帽 = 原始输入-开运算结果\n",
      "\n",
      "- 黑帽 = 闭运算-原始输入\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "#礼帽\n",
      "\n",
      "img = cv2.imread('images/dige.png')\n",
      "\n",
      "tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)\n",
      "\n",
      "plt_show(tophat)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_87_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "#黑帽\n",
      "\n",
      "img = cv2.imread('images/dige.png')\n",
      "\n",
      "blackhat  = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT, kernel)\n",
      "\n",
      "plt_show(blackhat)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_88_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 图像梯度-Sobel算子\n",
      "\n",
      "\n",
      "\n",
      "![title](images/sobel_1.png)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images/pie.png',cv2.IMREAD_GRAYSCALE)\n",
      "\n",
      "plt.imshow(img,cmap='gray')\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105d073a60>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_91_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "dst = cv2.Sobel(src, ddepth, dx, dy, ksize)\n",
      "\n",
      "- ddepth:图像的深度\n",
      "\n",
      "- dx和dy分别表示水平和竖直方向\n",
      "\n",
      "- ksize是Sobel算子的大小\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) #算水平梯度\n",
      "\n",
      "plt.imshow(sobelx,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x110598472e0>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_93_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "白到黑是正数，黑到白就是负数了，所有的负数会被截断成0，所以要取绝对值\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)\n",
      "\n",
      "sobelx = cv2.convertScaleAbs(sobelx)  #转换成绝对值\n",
      "\n",
      "plt.imshow(sobelx,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105969e490>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_95_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)\n",
      "\n",
      "sobely = cv2.convertScaleAbs(sobely)  \n",
      "\n",
      "plt.imshow(sobely,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x110596e8820>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_96_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "分别计算x和y，再求和\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)\n",
      "\n",
      "plt.imshow(sobelxy,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x11059704c70>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_98_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "不建议直接计算\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)\n",
      "\n",
      "sobelxy = cv2.convertScaleAbs(sobelxy) \n",
      "\n",
      "plt.imshow(sobelxy,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x11057f64eb0>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_100_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images/lena.jpg',cv2.IMREAD_GRAYSCALE)\n",
      "\n",
      "plt.imshow(img,cmap='gray')\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x110597fc400>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_101_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images/lena.jpg',cv2.IMREAD_GRAYSCALE)\n",
      "\n",
      "sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)\n",
      "\n",
      "sobelx = cv2.convertScaleAbs(sobelx)\n",
      "\n",
      "sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)\n",
      "\n",
      "sobely = cv2.convertScaleAbs(sobely)\n",
      "\n",
      "sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)\n",
      "\n",
      "plt.imshow(sobelxy,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x110596679d0>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_102_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images/lena.jpg',cv2.IMREAD_GRAYSCALE)\n",
      "\n",
      "sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)\n",
      "\n",
      "sobelxy = cv2.convertScaleAbs(sobelxy) \n",
      "\n",
      "plt.imshow(sobelxy,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105d0b3910>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_103_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 图像梯度-Scharr算子\n",
      "\n",
      "\n",
      "\n",
      "![title](images/scharr.png)\n",
      "\n",
      "\n",
      "\n",
      "### 图像梯度-laplacian算子\n",
      "\n",
      "对噪音敏感\n",
      "\n",
      "\n",
      "\n",
      "![title](images/l.png)\n",
      "\n",
      "\n",
      "\n",
      "### 不同算子的差异\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "#不同算子的差异\n",
      "\n",
      "img = cv2.imread('images/lena.jpg',cv2.IMREAD_GRAYSCALE)\n",
      "\n",
      "sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)\n",
      "\n",
      "sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)\n",
      "\n",
      "sobelx = cv2.convertScaleAbs(sobelx)   \n",
      "\n",
      "sobely = cv2.convertScaleAbs(sobely)  \n",
      "\n",
      "sobelxy =  cv2.addWeighted(sobelx,0.5,sobely,0.5,0)  \n",
      "\n",
      "\n",
      "\n",
      "scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)\n",
      "\n",
      "scharry = cv2.Scharr(img,cv2.CV_64F,0,1)\n",
      "\n",
      "scharrx = cv2.convertScaleAbs(scharrx)   \n",
      "\n",
      "scharry = cv2.convertScaleAbs(scharry)  \n",
      "\n",
      "scharrxy =  cv2.addWeighted(scharrx,0.5,scharry,0.5,0) \n",
      "\n",
      "\n",
      "\n",
      "laplacian = cv2.Laplacian(img,cv2.CV_64F)\n",
      "\n",
      "laplacian = cv2.convertScaleAbs(laplacian)   \n",
      "\n",
      "\n",
      "\n",
      "res = np.hstack((img,sobelxy,scharrxy,laplacian))\n",
      "\n",
      "plt.imshow(res,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x11059682490>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_109_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images/lena.jpg',cv2.IMREAD_GRAYSCALE)\n",
      "\n",
      "plt.imshow(img,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105954ef40>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_110_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### Canny边缘检测\n",
      "\n",
      "- 1)        使用高斯滤波器，以平滑图像，滤除噪声。\n",
      "\n",
      "\n",
      "\n",
      "- 2)        计算图像中每个像素点的梯度强度和方向。\n",
      "\n",
      "\n",
      "\n",
      "- 3)        应用非极大值（Non-Maximum Suppression）抑制，以消除边缘检测带来的杂散响应。\n",
      "\n",
      "\n",
      "\n",
      "- 4)        应用双阈值（Double-Threshold）检测来确定真实的和潜在的边缘。\n",
      "\n",
      "\n",
      "\n",
      "- 5)        通过抑制孤立的弱边缘最终完成边缘检测。\n",
      "\n",
      "\n",
      "\n",
      "#### 1:高斯滤波器\n",
      "\n",
      "\n",
      "\n",
      "![title](images/canny_1.png)\n",
      "\n",
      "\n",
      "\n",
      "#### 2:梯度和方向\n",
      "\n",
      "\n",
      "\n",
      "![title](images/canny_2.png)\n",
      "\n",
      "\n",
      "\n",
      "#### 3：非极大值抑制\n",
      "\n",
      "\n",
      "\n",
      "![title](images/canny_3.png)\n",
      "\n",
      "\n",
      "\n",
      "![title](images/canny_6.png)\n",
      "\n",
      "\n",
      "\n",
      "#### 4：双阈值检测\n",
      "\n",
      "\n",
      "\n",
      "![title](images/canny_5.png)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img=cv2.imread(\"images/lena.jpg\",cv2.IMREAD_GRAYSCALE)\n",
      "\n",
      "\n",
      "\n",
      "v1=cv2.Canny(img,80,150)\n",
      "\n",
      "v2=cv2.Canny(img,50,100)\n",
      "\n",
      "\n",
      "\n",
      "res = np.hstack((img,v1,v2))\n",
      "\n",
      "plt.imshow(res,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x11059669b80>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_121_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img=cv2.imread(\"images/car.png\",cv2.IMREAD_GRAYSCALE)\n",
      "\n",
      "\n",
      "\n",
      "v1=cv2.Canny(img,120,250)\n",
      "\n",
      "v2=cv2.Canny(img,50,100)\n",
      "\n",
      "\n",
      "\n",
      "res = np.hstack((v1,v2))\n",
      "\n",
      "plt.imshow(res,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x110595e26a0>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_122_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 图像金字塔\n",
      "\n",
      "- 高斯金字塔\n",
      "\n",
      "- 拉普拉斯金字塔\n",
      "\n",
      "\n",
      "\n",
      "![title](images/Pyramid_1.png)\n",
      "\n",
      "\n",
      "\n",
      "#### 高斯金字塔：向下采样方法（缩小）\n",
      "\n",
      "\n",
      "\n",
      "![title](images/Pyramid_2.png)\n",
      "\n",
      "\n",
      "\n",
      "#### 高斯金字塔：向上采样方法（放大）\n",
      "\n",
      "\n",
      "\n",
      "![title](images/Pyramid_3.png)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img=cv2.imread(\"images/AM.png\")\n",
      "\n",
      "plt_show(img)\n",
      "\n",
      "print (img.shape)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "    (442, 340, 3)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_129_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "up=cv2.pyrUp(img)\n",
      "\n",
      "plt_show(up)\n",
      "\n",
      "print (up.shape)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "    (884, 680, 3)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_130_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "down=cv2.pyrDown(img)\n",
      "\n",
      "plt_show(down)\n",
      "\n",
      "print (down.shape)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "    (221, 170, 3)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_131_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "up2=cv2.pyrUp(up)\n",
      "\n",
      "plt_show(up2)\n",
      "\n",
      "print (up2.shape)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "    (1768, 1360, 3)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_132_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "up=cv2.pyrUp(img)\n",
      "\n",
      "up_down=cv2.pyrDown(up)\n",
      "\n",
      "plt_show(up_down)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_133_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "plt_show(np.hstack((img,up_down)))\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_134_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "up=cv2.pyrUp(img)\n",
      "\n",
      "up_down=cv2.pyrDown(up)\n",
      "\n",
      "plt_show(img-up_down)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_135_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "#### 拉普拉斯金字塔\n",
      "\n",
      "\n",
      "\n",
      "![title](images/Pyramid_4.png)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "down=cv2.pyrDown(img)\n",
      "\n",
      "down_up=cv2.pyrUp(down)\n",
      "\n",
      "l_1=img-down_up\n",
      "\n",
      "plt_show(l_1)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_138_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 图像轮廓\n",
      "\n",
      "\n",
      "\n",
      "#### cv2.findContours(img,mode,method)\n",
      "\n",
      "mode:轮廓检索模式\n",
      "\n",
      "- RETR_EXTERNAL ：只检索最外面的轮廓；\n",
      "\n",
      "- RETR_LIST：检索所有的轮廓，并将其保存到一条链表当中；\n",
      "\n",
      "- RETR_CCOMP：检索所有的轮廓，并将他们组织为两层：顶层是各部分的外部边界，第二层是空洞的边界;\n",
      "\n",
      "- RETR_TREE：检索所有的轮廓，并重构嵌套轮廓的整个层次;(最常用)\n",
      "\n",
      "\n",
      "\n",
      "method:轮廓逼近方法\n",
      "\n",
      "- CHAIN_APPROX_NONE：以Freeman链码的方式输出轮廓，所有其他方法输出多边形（顶点的序列）。\n",
      "\n",
      "- CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分，也就是，函数只保留他们的终点部分。\n",
      "\n",
      "\n",
      "\n",
      "![title](images/chain.png)\n",
      "\n",
      "\n",
      "\n",
      "为了更高的准确率，使用二值图像。\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images/car.png')\n",
      "\n",
      "gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  #转换成灰度图\n",
      "\n",
      "ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) #二值处理\n",
      "\n",
      "plt.imshow(thresh,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105d1e4730>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_143_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "'''\n",
      "\n",
      "contours中每个元素都是图像中的一个轮廓，用numpy中的ndarray表示\n",
      "\n",
      "每个轮廓contours[i]对应4个hierarchy元素hierarchy[i][0] ~hierarchy[i][3]，分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号，如果没有对应项，则该值为负数。\n",
      "\n",
      "'''\n",
      "\n",
      "contours, hierarchy= cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)\n",
      "\n",
      "print('len(contours) : {}'.format(len(contours)))\n",
      "\n",
      "print('hierarchy.shape : {}'.format(hierarchy.shape))\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "    len(contours) : 2579\n",
      "\n",
      "    hierarchy.shape : (1, 2579, 4)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "绘制轮廓\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "plt_show(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_146_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "#传入绘制图像，轮廓，轮廓索引，颜色模式，线条厚度\n",
      "\n",
      "# 注意需要copy,要不原图会变。。。\n",
      "\n",
      "draw_img = img.copy()\n",
      "\n",
      "res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2)\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_147_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "draw_img = img.copy()\n",
      "\n",
      "res = cv2.drawContours(draw_img, contours, 0, (0, 0, 255), 2)\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_148_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "#### 轮廓特征\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "cnt = contours[0]\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "#面积\n",
      "\n",
      "cv2.contourArea(cnt)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    1.5\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "#周长，True表示闭合的\n",
      "\n",
      "cv2.arcLength(cnt,True)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    5.414213538169861\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "#### 轮廓近似\n",
      "\n",
      "\n",
      "\n",
      "![title](images/contours3.png)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images/contours2.png')\n",
      "\n",
      "\n",
      "\n",
      "gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n",
      "\n",
      "ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)\n",
      "\n",
      "contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)\n",
      "\n",
      "cnt = contours[0]\n",
      "\n",
      "\n",
      "\n",
      "draw_img = img.copy()\n",
      "\n",
      "res = cv2.drawContours(draw_img, [cnt], -1, (0, 0, 255), 2)\n",
      "\n",
      "\n",
      "\n",
      "plt_show(np.hstack([img,res]))\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_155_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "epsilon = 0.15*cv2.arcLength(cnt,True) \n",
      "\n",
      "approx = cv2.approxPolyDP(cnt,epsilon,True)\n",
      "\n",
      "\n",
      "\n",
      "draw_img = img.copy()\n",
      "\n",
      "res = cv2.drawContours(draw_img, [approx], -1, (0, 0, 255), 2)\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_156_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "边界矩形\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images/contours.png')\n",
      "\n",
      "\n",
      "\n",
      "gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n",
      "\n",
      "ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)\n",
      "\n",
      "contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)\n",
      "\n",
      "cnt = contours[0]\n",
      "\n",
      "\n",
      "\n",
      "# 边界矩形\n",
      "\n",
      "x,y,w,h = cv2.boundingRect(cnt)\n",
      "\n",
      "img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)\n",
      "\n",
      "plt_show(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_158_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "area = cv2.contourArea(cnt)\n",
      "\n",
      "x, y, w, h = cv2.boundingRect(cnt)\n",
      "\n",
      "rect_area = w * h\n",
      "\n",
      "extent = float(area) / rect_area\n",
      "\n",
      "print ('轮廓面积与边界矩形比',extent)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "    轮廓面积与边界矩形比 0.5154317244724715\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "外接圆\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "(x,y),radius = cv2.minEnclosingCircle(cnt) \n",
      "\n",
      "center = (int(x),int(y)) \n",
      "\n",
      "radius = int(radius) \n",
      "\n",
      "img = cv2.circle(img,center,radius,(0,255,0),2)\n",
      "\n",
      "plt_show(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_161_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 傅里叶变换\n",
      "\n",
      "\n",
      "\n",
      "我们生活在时间的世界中，早上7:00起来吃早饭，8:00去挤地铁，9:00开始上班。。。以时间为参照就是时域分析。\n",
      "\n",
      "\n",
      "\n",
      "但是在频域中一切都是静止的！\n",
      "\n",
      "\n",
      "\n",
      "https://zhuanlan.zhihu.com/p/19763358\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 傅里叶变换的作用\n",
      "\n",
      "\n",
      "\n",
      "- 高频：变化剧烈的灰度分量，例如边界\n",
      "\n",
      "\n",
      "\n",
      "- 低频：变化缓慢的灰度分量，例如一片大海\n",
      "\n",
      "\n",
      "\n",
      "### 滤波\n",
      "\n",
      "\n",
      "\n",
      "- 低通滤波器：只保留低频，会使得图像模糊\n",
      "\n",
      "\n",
      "\n",
      "- 高通滤波器：只保留高频，会使得图像细节增强\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "- opencv中主要就是cv2.dft()和cv2.idft()，输入图像需要先转换成np.float32 格式。\n",
      "\n",
      "- 得到的结果中频率为0的部分会在左上角，通常要转换到中心位置，可以通过shift变换来实现。\n",
      "\n",
      "- cv2.dft()返回的结果是双通道的（实部，虚部），通常还需要转换成图像格式才能展示（0,255）。\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "import numpy as np\n",
      "\n",
      "import cv2\n",
      "\n",
      "from matplotlib import pyplot as plt\n",
      "\n",
      "\n",
      "\n",
      "img = cv2.imread('images/lena.jpg',0)\n",
      "\n",
      "img_float32 = np.float32(img)\n",
      "\n",
      "\n",
      "\n",
      "dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)\n",
      "\n",
      "dft_shift = np.fft.fftshift(dft)\n",
      "\n",
      "# 得到灰度图能表示的形式\n",
      "\n",
      "magnitude_spectrum = 20*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))\n",
      "\n",
      "\n",
      "\n",
      "plt.subplot(121),plt.imshow(img, cmap = 'gray')\n",
      "\n",
      "plt.title('Input Image'), plt.xticks([]), plt.yticks([])\n",
      "\n",
      "\n",
      "\n",
      "plt.subplot(122),plt.imshow(magnitude_spectrum, cmap = 'gray')\n",
      "\n",
      "plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])\n",
      "\n",
      "\n",
      "\n",
      "plt.show()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_166_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "import numpy as np\n",
      "\n",
      "import cv2\n",
      "\n",
      "from matplotlib import pyplot as plt\n",
      "\n",
      "\n",
      "\n",
      "img = cv2.imread('images/lena.jpg',0)\n",
      "\n",
      "\n",
      "\n",
      "img_float32 = np.float32(img)\n",
      "\n",
      "\n",
      "\n",
      "dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)\n",
      "\n",
      "dft_shift = np.fft.fftshift(dft)\n",
      "\n",
      "\n",
      "\n",
      "rows, cols = img.shape\n",
      "\n",
      "crow, ccol = int(rows/2) , int(cols/2)     # 中心位置\n",
      "\n",
      "\n",
      "\n",
      "# 低通滤波\n",
      "\n",
      "mask = np.zeros((rows, cols, 2), np.uint8)\n",
      "\n",
      "mask[crow-30:crow+30, ccol-30:ccol+30] = 1\n",
      "\n",
      "\n",
      "\n",
      "# IDFT\n",
      "\n",
      "fshift = dft_shift*mask\n",
      "\n",
      "f_ishift = np.fft.ifftshift(fshift)\n",
      "\n",
      "img_back = cv2.idft(f_ishift)\n",
      "\n",
      "img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])\n",
      "\n",
      "\n",
      "\n",
      "plt.subplot(121),plt.imshow(img, cmap = 'gray')\n",
      "\n",
      "plt.title('Input Image'), plt.xticks([]), plt.yticks([])\n",
      "\n",
      "plt.subplot(122),plt.imshow(img_back, cmap = 'gray')\n",
      "\n",
      "plt.title('Result'), plt.xticks([]), plt.yticks([])\n",
      "\n",
      "\n",
      "\n",
      "plt.show()                \n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_167_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images/lena.jpg',0)\n",
      "\n",
      "\n",
      "\n",
      "img_float32 = np.float32(img)\n",
      "\n",
      "\n",
      "\n",
      "dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)\n",
      "\n",
      "dft_shift = np.fft.fftshift(dft)\n",
      "\n",
      "\n",
      "\n",
      "rows, cols = img.shape\n",
      "\n",
      "crow, ccol = int(rows/2) , int(cols/2)     # 中心位置\n",
      "\n",
      "\n",
      "\n",
      "# 高通滤波\n",
      "\n",
      "mask = np.ones((rows, cols, 2), np.uint8)\n",
      "\n",
      "mask[crow-30:crow+30, ccol-30:ccol+30] = 0\n",
      "\n",
      "\n",
      "\n",
      "# IDFT\n",
      "\n",
      "fshift = dft_shift*mask\n",
      "\n",
      "f_ishift = np.fft.ifftshift(fshift)\n",
      "\n",
      "img_back = cv2.idft(f_ishift)\n",
      "\n",
      "img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])\n",
      "\n",
      "\n",
      "\n",
      "plt.subplot(121),plt.imshow(img, cmap = 'gray')\n",
      "\n",
      "plt.title('Input Image'), plt.xticks([]), plt.yticks([])\n",
      "\n",
      "plt.subplot(122),plt.imshow(img_back, cmap = 'gray')\n",
      "\n",
      "plt.title('Result'), plt.xticks([]), plt.yticks([])\n",
      "\n",
      "\n",
      "\n",
      "plt.show()    \n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_168_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "import cv2 #opencv读取的格式是BGR\n",
      "\n",
      "import numpy as np\n",
      "\n",
      "import matplotlib.pyplot as plt#Matplotlib是RGB\n",
      "\n",
      "%matplotlib inline \n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "### 直方图\n",
      "\n",
      "\n",
      "\n",
      "![title](images/hist_1.png)\n",
      "\n",
      "\n",
      "\n",
      "#### cv2.calcHist(images,channels,mask,histSize,ranges)\n",
      "\n",
      "\n",
      "\n",
      "- images: 原图像图像格式为 uint8 或 ﬂoat32。当传入函数时应 用中括号 [] 括来例如[img]\n",
      "\n",
      "- channels: 同样用中括号括来它会告函数我们统幅图 像的直方图。如果入图像是灰度图它的值就是 [0]如果是彩色图像 的传入的参数可以是 [0][1][2] 它们分别对应着 BGR。 \n",
      "\n",
      "- mask: 掩模图像。统计整幅图像的直方图就把它为 None。但是如 果你想统计图像某一部分的直方图的你就制作一个掩模图像并 使用它。\n",
      "\n",
      "- histSize:BIN 的数目。也应用中括号括来\n",
      "\n",
      "- ranges: 像素值范围常为 [0,256] \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images/cat.jpg',0) #0表示灰度图\n",
      "\n",
      "hist = cv2.calcHist([img],[0],None,[256],[0,256])\n",
      "\n",
      "hist.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (256, 1)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "plt.hist(img.ravel(),256); \n",
      "\n",
      "plt.show()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_174_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images/cat.jpg') \n",
      "\n",
      "color = ('b','g','r')\n",
      "\n",
      "for i,col in enumerate(color): \n",
      "\n",
      "    histr = cv2.calcHist([img],[i],None,[256],[0,256]) \n",
      "\n",
      "    plt.plot(histr,color = col) \n",
      "\n",
      "    plt.xlim([0,256]) \n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_175_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "mask操作\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 创建mask\n",
      "\n",
      "mask = np.zeros(img.shape[:2], np.uint8)\n",
      "\n",
      "print (mask.shape)\n",
      "\n",
      "mask[100:300, 100:400] = 255\n",
      "\n",
      "plt.imshow(mask,cmap=plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "    (414, 500)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105cf7d2e0>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_177_2.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images/cat.jpg', 0)\n",
      "\n",
      "plt.imshow(img,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105d30ca30>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_178_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "masked_img = cv2.bitwise_and(img, img, mask=mask)#与操作\n",
      "\n",
      "plt.imshow(masked_img,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105d161d90>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_179_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "hist_full = cv2.calcHist([img], [0], None, [256], [0, 256])\n",
      "\n",
      "hist_mask = cv2.calcHist([img], [0], mask, [256], [0, 256])\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "plt.subplot(221), plt.imshow(img, 'gray')\n",
      "\n",
      "plt.subplot(222), plt.imshow(mask, 'gray')\n",
      "\n",
      "plt.subplot(223), plt.imshow(masked_img, 'gray')\n",
      "\n",
      "plt.subplot(224), plt.plot(hist_full), plt.plot(hist_mask)\n",
      "\n",
      "plt.xlim([0, 256])\n",
      "\n",
      "plt.show()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_181_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "#### 直方图均衡化\n",
      "\n",
      "\n",
      "\n",
      "![title](images/hist_2.png)\n",
      "\n",
      "\n",
      "\n",
      "![title](images/hist_3.png)\n",
      "\n",
      "\n",
      "\n",
      "![title](images/hist_4.png)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images/clahe.jpg',0) #0表示灰度图 #clahe\n",
      "\n",
      "plt.hist(img.ravel(),256); \n",
      "\n",
      "plt.show()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_186_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "equ = cv2.equalizeHist(img) \n",
      "\n",
      "plt.hist(equ.ravel(),256)\n",
      "\n",
      "plt.show()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_187_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "res = np.hstack((img,equ))\n",
      "\n",
      "plt.imshow(res,cmap='gray')\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105cf4b7c0>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_188_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "#### 自适应直方图均衡化\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) \n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "res_clahe = clahe.apply(img)\n",
      "\n",
      "res = np.hstack((img,equ,res_clahe))\n",
      "\n",
      "plt.imshow(res,cmap='gray')\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105d263580>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_191_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 模板匹配\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "模板匹配和卷积原理很像，模板在原图像上从原点开始滑动，计算模板与（图像被模板覆盖的地方）的差别程度，这个差别程度的计算方法在opencv里有6种，然后将每次计算的结果放入一个矩阵里，作为结果输出。假如原图形是AxB大小，而模板是axb大小，则输出结果的矩阵是(A-a+1)x(B-b+1)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 模板匹配\n",
      "\n",
      "img = cv2.imread('images/lena.jpg', 0)\n",
      "\n",
      "template = cv2.imread('images/face.jpg', 0)\n",
      "\n",
      "h, w = template.shape[:2] \n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (263, 263)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "template.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (110, 85)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "- TM_SQDIFF：计算平方不同，计算出来的值越小，越相关        \n",
      "\n",
      "- TM_CCORR：计算相关性，计算出来的值越大，越相关\n",
      "\n",
      "- TM_CCOEFF：计算相关系数，计算出来的值越大，越相关\n",
      "\n",
      "- TM_SQDIFF_NORMED：计算归一化平方不同，计算出来的值越接近0，越相关\n",
      "\n",
      "- TM_CCORR_NORMED：计算归一化相关性，计算出来的值越接近1，越相关\n",
      "\n",
      "- TM_CCOEFF_NORMED：计算归一化相关系数，计算出来的值越接近1，越相关\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "公式：https://docs.opencv.org/3.3.1/df/dfb/group__imgproc__object.html#ga3a7850640f1fe1f58fe91a2d7583695d\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',\n",
      "\n",
      "           'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "res = cv2.matchTemplate(img, template, cv2.TM_SQDIFF)\n",
      "\n",
      "res.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (154, 179)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "min_val\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    39168.0\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "max_val\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    74403584.0\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "min_loc\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (107, 89)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "max_loc\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (159, 62)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "for meth in methods:\n",
      "\n",
      "    img2 = img.copy()\n",
      "\n",
      "\n",
      "\n",
      "    # 匹配方法的真值\n",
      "\n",
      "    method = eval(meth)\n",
      "\n",
      "    print (meth)\n",
      "\n",
      "    res = cv2.matchTemplate(img, template, method)\n",
      "\n",
      "    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)\n",
      "\n",
      "\n",
      "\n",
      "    # 如果是平方差匹配TM_SQDIFF或归一化平方差匹配TM_SQDIFF_NORMED，取最小值\n",
      "\n",
      "    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:\n",
      "\n",
      "        top_left = min_loc\n",
      "\n",
      "    else:\n",
      "\n",
      "        top_left = max_loc\n",
      "\n",
      "    bottom_right = (top_left[0] + w, top_left[1] + h)\n",
      "\n",
      "\n",
      "\n",
      "    # 画矩形\n",
      "\n",
      "    cv2.rectangle(img2, top_left, bottom_right, 255, 2)\n",
      "\n",
      "\n",
      "\n",
      "    plt.subplot(121), plt.imshow(res, cmap='gray')\n",
      "\n",
      "    plt.xticks([]), plt.yticks([])  # 隐藏坐标轴\n",
      "\n",
      "    plt.subplot(122), plt.imshow(img2, cmap='gray')\n",
      "\n",
      "    plt.xticks([]), plt.yticks([])\n",
      "\n",
      "    plt.suptitle(meth)\n",
      "\n",
      "    plt.show()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "    cv2.TM_CCOEFF\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_206_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    cv2.TM_CCOEFF_NORMED\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_206_3.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    cv2.TM_CCORR\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_206_5.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    cv2.TM_CCORR_NORMED\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_206_7.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    cv2.TM_SQDIFF\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_206_9.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    cv2.TM_SQDIFF_NORMED\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_206_11.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 匹配多个对象\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img_rgb = cv2.imread('images/mario.jpg')\n",
      "\n",
      "img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)\n",
      "\n",
      "template = cv2.imread('images/mario_coin.jpg', 0)\n",
      "\n",
      "h, w = template.shape[:2]\n",
      "\n",
      "\n",
      "\n",
      "res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)\n",
      "\n",
      "threshold = 0.8\n",
      "\n",
      "# 取匹配程度大于%80的坐标\n",
      "\n",
      "loc = np.where(res >= threshold)\n",
      "\n",
      "for pt in zip(*loc[::-1]):  # *号表示可选参数\n",
      "\n",
      "    bottom_right = (pt[0] + w, pt[1] + h)\n",
      "\n",
      "    cv2.rectangle(img_rgb, pt, bottom_right, (0, 0, 255), 2)\n",
      "\n",
      "\n",
      "\n",
      "plt.imshow(img_rgb[:,:,[2,1,0]])\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105d5fc490>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](output_208_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "lines=[]\n",
    "with open('图像基本操作.md','r',encoding='utf-8') as f:\n",
    "    lines=f.readlines()\n",
    "\n",
    "    \n",
    "for line in lines:\n",
    "    print(line)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "443c2ac8-56bd-424d-86c5-9e2b3b8a0f9a",
   "metadata": {},
   "outputs": [],
   "source": [
    "def changeOutFilename(temstr):\n",
    "    def fun(tem):\n",
    "        tem=str(tem.group())\n",
    "        return 'images_图像基本操作/output/{}'.format(tem)\n",
    "    \n",
    "    res=re.sub('output\\w+.png',fun,temstr)\n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "a2b7b983-2896-4b5d-afa2-dd6e8ad0390c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def changeImageFilename(temstr):\n",
    "    def fun(tem):\n",
    "        filename=tem.group(2)\n",
    "        return 'images_图像基本操作/{}'.format(filename)\n",
    "\n",
    "    res=re.sub('(images)/(\\w+.\\w{3,3})',fun,temstr)\n",
    "    return res"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "28dc405c-b12c-4114-9c5f-2b884021fe26",
   "metadata": {},
   "outputs": [],
   "source": [
    "for index,line in enumerate(lines):\n",
    "    lines[index]=changeOutFilename(line)\n",
    "    # lines[index]=changeImageFilename(line)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "f4d03c81-0622-48a6-9be4-83bd9adba4a6",
   "metadata": {
    "collapsed": true,
    "jupyter": {
     "outputs_hidden": true
    },
    "tags": []
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "## 图像基本操作\n",
      "\n",
      "\n",
      "\n",
      "#### 环境配置地址：\n",
      "\n",
      "\n",
      "\n",
      "- Anaconda:https://www.anaconda.com/download/\n",
      "\n",
      "\n",
      "\n",
      "- Python_whl:https://www.lfd.uci.edu/~gohlke/pythonlibs/#opencv\n",
      "\n",
      "\n",
      "\n",
      "- eclipse:按照自己的喜好，选择一个能debug就好\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/lena_img.png)\n",
      "\n",
      "\n",
      "\n",
      "### 数据读取-图像\n",
      "\n",
      "\n",
      "\n",
      "- cv2.IMREAD_COLOR：彩色图像\n",
      "\n",
      "- cv2.IMREAD_GRAYSCALE：灰度图像\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "import cv2 #opencv读取的格式是BGR\n",
      "\n",
      "import matplotlib.pyplot as plt\n",
      "\n",
      "import numpy as np \n",
      "\n",
      "%matplotlib inline \n",
      "\n",
      "\n",
      "\n",
      "img=cv2.imread('images_图像基本操作/cat.jpg')\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    array([[[142, 151, 160],\n",
      "\n",
      "            [146, 155, 164],\n",
      "\n",
      "            [151, 160, 170],\n",
      "\n",
      "            ...,\n",
      "\n",
      "            [156, 172, 185],\n",
      "\n",
      "            [155, 171, 184],\n",
      "\n",
      "            [154, 170, 183]],\n",
      "\n",
      "    \n",
      "\n",
      "           [[108, 117, 126],\n",
      "\n",
      "            [112, 123, 131],\n",
      "\n",
      "            [118, 127, 137],\n",
      "\n",
      "            ...,\n",
      "\n",
      "            [155, 171, 184],\n",
      "\n",
      "            [154, 170, 183],\n",
      "\n",
      "            [153, 169, 182]],\n",
      "\n",
      "    \n",
      "\n",
      "           [[108, 119, 127],\n",
      "\n",
      "            [110, 123, 131],\n",
      "\n",
      "            [118, 128, 138],\n",
      "\n",
      "            ...,\n",
      "\n",
      "            [156, 169, 183],\n",
      "\n",
      "            [155, 168, 182],\n",
      "\n",
      "            [154, 167, 181]],\n",
      "\n",
      "    \n",
      "\n",
      "           ...,\n",
      "\n",
      "    \n",
      "\n",
      "           [[162, 186, 198],\n",
      "\n",
      "            [157, 181, 193],\n",
      "\n",
      "            [142, 166, 178],\n",
      "\n",
      "            ...,\n",
      "\n",
      "            [181, 204, 206],\n",
      "\n",
      "            [170, 193, 195],\n",
      "\n",
      "            [149, 172, 174]],\n",
      "\n",
      "    \n",
      "\n",
      "           [[140, 164, 176],\n",
      "\n",
      "            [147, 171, 183],\n",
      "\n",
      "            [139, 163, 175],\n",
      "\n",
      "            ...,\n",
      "\n",
      "            [169, 187, 188],\n",
      "\n",
      "            [125, 143, 144],\n",
      "\n",
      "            [106, 124, 125]],\n",
      "\n",
      "    \n",
      "\n",
      "           [[154, 178, 190],\n",
      "\n",
      "            [154, 178, 190],\n",
      "\n",
      "            [121, 145, 157],\n",
      "\n",
      "            ...,\n",
      "\n",
      "            [183, 198, 200],\n",
      "\n",
      "            [128, 143, 145],\n",
      "\n",
      "            [127, 142, 144]]], dtype=uint8)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "#图像的显示,也可以创建多个窗口\n",
      "\n",
      "cv2.imshow('image',img) \n",
      "\n",
      "# 等待时间，毫秒级，0表示任意键终止\n",
      "\n",
      "cv2.waitKey(0) \n",
      "\n",
      "cv2.destroyAllWindows()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "def cv_show(name,img):\n",
      "\n",
      "    cv2.imshow(name,img) \n",
      "\n",
      "    cv2.waitKey(0) \n",
      "\n",
      "    cv2.destroyAllWindows()\n",
      "\n",
      "\n",
      "\n",
      "def plt_show(img):\n",
      "\n",
      "    # opencv读取的是BGR格式 plt展示的是RGB格式 因此需要进行通道的转换\n",
      "\n",
      "    img=img[:,:,[2,1,0]]\n",
      "\n",
      "    plt.imshow(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "plt_show(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_9_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (414, 500, 3)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img=cv2.imread('images_图像基本操作/cat.jpg',cv2.IMREAD_GRAYSCALE) #读取灰度图\n",
      "\n",
      "img\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    array([[153, 157, 162, ..., 174, 173, 172],\n",
      "\n",
      "           [119, 124, 129, ..., 173, 172, 171],\n",
      "\n",
      "           [120, 124, 130, ..., 172, 171, 170],\n",
      "\n",
      "           ...,\n",
      "\n",
      "           [187, 182, 167, ..., 202, 191, 170],\n",
      "\n",
      "           [165, 172, 164, ..., 185, 141, 122],\n",
      "\n",
      "           [179, 179, 146, ..., 197, 142, 141]], dtype=uint8)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (414, 500)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "#保存\n",
      "\n",
      "cv2.imwrite('images_图像基本操作/mycat.png',img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    True\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "type(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    numpy.ndarray\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img.size\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    207000\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img.dtype\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    dtype('uint8')\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 数据读取-视频\n",
      "\n",
      "\n",
      "\n",
      "- cv2.VideoCapture可以捕获摄像头，用数字来控制不同的设备，例如0,1。\n",
      "\n",
      "- 如果是视频文件，直接指定好路径即可。\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "vc = cv2.VideoCapture('images_图像基本操作/test.mp4')\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 检查是否打开正确\n",
      "\n",
      "if vc.isOpened(): \n",
      "\n",
      "    open, frame = vc.read()  #每次读取一帧\n",
      "\n",
      "else:\n",
      "\n",
      "    open = False\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "while open:\n",
      "\n",
      "    ret, frame = vc.read()\n",
      "\n",
      "    if frame is None:\n",
      "\n",
      "        break\n",
      "\n",
      "    if ret == True:\n",
      "\n",
      "        gray = cv2.cvtColor(frame,  cv2.COLOR_BGR2GRAY) #转换成灰度图\n",
      "\n",
      "        cv2.imshow('result', gray)\n",
      "\n",
      "        if cv2.waitKey(100) & 0xFF == 27:\n",
      "\n",
      "            break\n",
      "\n",
      "vc.release()\n",
      "\n",
      "cv2.destroyAllWindows()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "### 截取部分图像数据\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img=cv2.imread('images_图像基本操作/cat.jpg')\n",
      "\n",
      "cat=img[0:50,0:200] \n",
      "\n",
      "plt_show(cat)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_23_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 颜色通道提取\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "b,g,r=cv2.split(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "r\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    array([[160, 164, 170, ..., 185, 184, 183],\n",
      "\n",
      "           [126, 131, 137, ..., 184, 183, 182],\n",
      "\n",
      "           [127, 131, 138, ..., 183, 182, 181],\n",
      "\n",
      "           ...,\n",
      "\n",
      "           [198, 193, 178, ..., 206, 195, 174],\n",
      "\n",
      "           [176, 183, 175, ..., 188, 144, 125],\n",
      "\n",
      "           [190, 190, 157, ..., 200, 145, 144]], dtype=uint8)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "r.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (414, 500)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img=cv2.merge((b,g,r))\n",
      "\n",
      "img.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (414, 500, 3)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 只保留R\n",
      "\n",
      "cur_img = img.copy()\n",
      "\n",
      "cur_img[:,:,0] = 0\n",
      "\n",
      "cur_img[:,:,1] = 0\n",
      "\n",
      "plt_show(cur_img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_29_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 只保留G\n",
      "\n",
      "cur_img = img.copy()\n",
      "\n",
      "cur_img[:,:,0] = 0\n",
      "\n",
      "cur_img[:,:,2] = 0\n",
      "\n",
      "plt_show(cur_img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_30_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 只保留B\n",
      "\n",
      "cur_img = img.copy()\n",
      "\n",
      "cur_img[:,:,1] = 0\n",
      "\n",
      "cur_img[:,:,2] = 0\n",
      "\n",
      "plt_show(cur_img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_31_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 边界填充\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "top_size,bottom_size,left_size,right_size = (50,50,50,50)  #上下左右\n",
      "\n",
      "\n",
      "\n",
      "replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)\n",
      "\n",
      "reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_REFLECT)\n",
      "\n",
      "reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT_101)\n",
      "\n",
      "wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_WRAP)\n",
      "\n",
      "constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_CONSTANT, value=0)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "import matplotlib.pyplot as plt\n",
      "\n",
      "plt.subplot(231), plt.imshow(img, 'gray'), plt.title('ORIGINAL')\n",
      "\n",
      "plt.subplot(232), plt.imshow(replicate, 'gray'), plt.title('REPLICATE')\n",
      "\n",
      "plt.subplot(233), plt.imshow(reflect, 'gray'), plt.title('REFLECT')\n",
      "\n",
      "plt.subplot(234), plt.imshow(reflect101, 'gray'), plt.title('REFLECT_101')\n",
      "\n",
      "plt.subplot(235), plt.imshow(wrap, 'gray'), plt.title('WRAP')\n",
      "\n",
      "plt.subplot(236), plt.imshow(constant, 'gray'), plt.title('CONSTANT')\n",
      "\n",
      "\n",
      "\n",
      "plt.show()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_34_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "- BORDER_REPLICATE：复制法，也就是复制最边缘像素。\n",
      "\n",
      "- BORDER_REFLECT：反射法，对感兴趣的图像中的像素在两边进行复制例如：fedcba|abcdefgh|hgfedcb   \n",
      "\n",
      "- BORDER_REFLECT_101：反射法，也就是以最边缘像素为轴，对称，gfedcb|abcdefgh|gfedcba\n",
      "\n",
      "- BORDER_WRAP：外包装法cdefgh|abcdefgh|abcdefg  \n",
      "\n",
      "- BORDER_CONSTANT：常量法，常数值填充。\n",
      "\n",
      "\n",
      "\n",
      "### 数值计算\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img_cat=cv2.imread('images_图像基本操作/cat.jpg')\n",
      "\n",
      "img_dog=cv2.imread('images_图像基本操作/dog.jpg')\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img_cat2= img_cat +10 \n",
      "\n",
      "img_cat[:5,:,0]\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    array([[142, 146, 151, ..., 156, 155, 154],\n",
      "\n",
      "           [108, 112, 118, ..., 155, 154, 153],\n",
      "\n",
      "           [108, 110, 118, ..., 156, 155, 154],\n",
      "\n",
      "           [139, 141, 148, ..., 156, 155, 154],\n",
      "\n",
      "           [153, 156, 163, ..., 160, 159, 158]], dtype=uint8)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img_cat2[:5,:,0]\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    array([[152, 156, 161, ..., 166, 165, 164],\n",
      "\n",
      "           [118, 122, 128, ..., 165, 164, 163],\n",
      "\n",
      "           [118, 120, 128, ..., 166, 165, 164],\n",
      "\n",
      "           [149, 151, 158, ..., 166, 165, 164],\n",
      "\n",
      "           [163, 166, 173, ..., 170, 169, 168]], dtype=uint8)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "#相当于% 256\n",
      "\n",
      "(img_cat + img_cat2)[:5,:,0] \n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    array([[ 38,  46,  56, ...,  66,  64,  62],\n",
      "\n",
      "           [226, 234, 246, ...,  64,  62,  60],\n",
      "\n",
      "           [226, 230, 246, ...,  66,  64,  62],\n",
      "\n",
      "           [ 32,  36,  50, ...,  66,  64,  62],\n",
      "\n",
      "           [ 60,  66,  80, ...,  74,  72,  70]], dtype=uint8)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "cv2.add(img_cat,img_cat2)[:5,:,0]\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    array([[255, 255, 255, ..., 255, 255, 255],\n",
      "\n",
      "           [226, 234, 246, ..., 255, 255, 255],\n",
      "\n",
      "           [226, 230, 246, ..., 255, 255, 255],\n",
      "\n",
      "           [255, 255, 255, ..., 255, 255, 255],\n",
      "\n",
      "           [255, 255, 255, ..., 255, 255, 255]], dtype=uint8)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 图像融合\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 尺寸不同不能相加\n",
      "\n",
      "# img_cat + img_dog\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img_cat.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (414, 500, 3)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img_dog = cv2.resize(img_dog, (500, 414))\n",
      "\n",
      "img_dog.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (414, 500, 3)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "res = cv2.addWeighted(img_cat, 0.4, img_dog, 0.6, 0)  #图像融合 ax+by+c\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_47_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "res = cv2.resize(img, (0, 0), fx=4, fy=4)  #按比例缩放\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_48_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "res = cv2.resize(img, (0, 0), fx=1, fy=3)\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_49_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 灰度图\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "import cv2 #opencv读取的格式是BGR\n",
      "\n",
      "import numpy as np\n",
      "\n",
      "import matplotlib.pyplot as plt #Matplotlib是RGB\n",
      "\n",
      "%matplotlib inline \n",
      "\n",
      "\n",
      "\n",
      "img=cv2.imread('images_图像基本操作/cat.jpg')\n",
      "\n",
      "img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)\n",
      "\n",
      "img_gray.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (414, 500)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "def plt_show(img):\n",
      "\n",
      "    # opencv读取的是BGR格式 plt展示的是RGB格式 因此需要进行通道的转换\n",
      "\n",
      "    img=img[:,:,[2,1,0]]\n",
      "\n",
      "    plt.imshow(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "cv2.imshow('img_gray',img_gray) \n",
      "\n",
      "cv2.waitKey(0) \n",
      "\n",
      "cv2.destroyAllWindows()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "plt.imshow(img_gray,cmap='gray')\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x110598d3520>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_54_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### HSV\n",
      "\n",
      "- H - 色调（主波长）。 \n",
      "\n",
      "- S - 饱和度（纯度/颜色的阴影）。 \n",
      "\n",
      "- V值（强度）\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)\n",
      "\n",
      "plt_show(hsv)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_56_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 图像阈值\n",
      "\n",
      "\n",
      "\n",
      "#### ret, dst = cv2.threshold(src, thresh, maxval, type)\n",
      "\n",
      "\n",
      "\n",
      "- src： 输入图，只能输入单通道图像，通常来说为灰度图\n",
      "\n",
      "- dst： 输出图\n",
      "\n",
      "- thresh： 阈值\n",
      "\n",
      "- maxval： 当像素值超过了阈值（或者小于阈值，根据type来决定），所赋予的值\n",
      "\n",
      "- type：二值化操作的类型，包含以下5种类型： cv2.THRESH_BINARY； cv2.THRESH_BINARY_INV； cv2.THRESH_TRUNC； cv2.THRESH_TOZERO；cv2.THRESH_TOZERO_INV\n",
      "\n",
      "\n",
      "\n",
      "- cv2.THRESH_BINARY           超过阈值部分取maxval（最大值），否则取0\n",
      "\n",
      "- cv2.THRESH_BINARY_INV    THRESH_BINARY的反转\n",
      "\n",
      "- cv2.THRESH_TRUNC            大于阈值部分设为阈值，否则不变\n",
      "\n",
      "- cv2.THRESH_TOZERO          大于阈值部分不改变，否则设为0\n",
      "\n",
      "- cv2.THRESH_TOZERO_INV  THRESH_TOZERO的反转\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)\n",
      "\n",
      "ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)\n",
      "\n",
      "ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)\n",
      "\n",
      "ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)\n",
      "\n",
      "ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)\n",
      "\n",
      "\n",
      "\n",
      "titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']\n",
      "\n",
      "images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]\n",
      "\n",
      "\n",
      "\n",
      "for i in range(6):\n",
      "\n",
      "    plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')\n",
      "\n",
      "    plt.title(titles[i])\n",
      "\n",
      "    plt.xticks([]), plt.yticks([])\n",
      "\n",
      "plt.show()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_58_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 图像平滑\n",
      "\n",
      "\n",
      "\n",
      "![images_图像基本操作/image.png](attachment:image.png)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/lenaNoise.png')\n",
      "\n",
      "plt_show(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_61_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 均值滤波\n",
      "\n",
      "# 简单的平均卷积操作\n",
      "\n",
      "blur = cv2.blur(img, (3, 3))\n",
      "\n",
      "plt_show(blur)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_62_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 方框滤波\n",
      "\n",
      "# 基本和均值一样，可以选择归一化\n",
      "\n",
      "box = cv2.boxFilter(img,-1,(3,3), normalize=True)  \n",
      "\n",
      "plt_show(box)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_63_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 方框滤波\n",
      "\n",
      "# 基本和均值一样，可以选择归一化,容易越界\n",
      "\n",
      "box = cv2.boxFilter(img,-1,(3,3), normalize=False)  \n",
      "\n",
      "plt_show(box)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_64_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 高斯滤波\n",
      "\n",
      "# 高斯模糊的卷积核里的数值是满足高斯分布，相当于更重视中间的\n",
      "\n",
      "aussian = cv2.GaussianBlur(img, (5, 5), 1)  \n",
      "\n",
      "plt_show(aussian)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_65_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 中值滤波\n",
      "\n",
      "# 相当于用中值代替\n",
      "\n",
      "median = cv2.medianBlur(img, 5)  # 中值滤波\n",
      "\n",
      "plt_show(median)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_66_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 展示所有的\n",
      "\n",
      "res = np.hstack((blur,aussian,median))\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_67_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 形态学-腐蚀操作\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/dige.png')\n",
      "\n",
      "plt_show(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_69_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "kernel = np.ones((3,3),np.uint8) \n",
      "\n",
      "erosion = cv2.erode(img,kernel,iterations = 1)\n",
      "\n",
      "plt_show(erosion)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_70_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "pie = cv2.imread('images_图像基本操作/pie.png')\n",
      "\n",
      "plt_show(pie)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_71_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "kernel = np.ones((30,30),np.uint8) \n",
      "\n",
      "erosion_1 = cv2.erode(pie,kernel,iterations = 1)\n",
      "\n",
      "erosion_2 = cv2.erode(pie,kernel,iterations = 2)\n",
      "\n",
      "erosion_3 = cv2.erode(pie,kernel,iterations = 3)\n",
      "\n",
      "res = np.hstack((erosion_1,erosion_2,erosion_3))\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_72_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 形态学-膨胀操作\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/dige.png')\n",
      "\n",
      "plt_show(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_74_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "#### 先做腐蚀操作\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "kernel = np.ones((3,3),np.uint8) \n",
      "\n",
      "dige_erosion = cv2.erode(img,kernel,iterations = 1)\n",
      "\n",
      "plt_show(dige_erosion)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_76_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "#### 再做膨胀操作\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "kernel = np.ones((3,3),np.uint8) \n",
      "\n",
      "dige_dilate = cv2.dilate(dige_erosion,kernel,iterations = 1)\n",
      "\n",
      "plt_show(dige_dilate)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_78_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "pie = cv2.imread('images_图像基本操作/pie.png')\n",
      "\n",
      "\n",
      "\n",
      "kernel = np.ones((30,30),np.uint8) \n",
      "\n",
      "dilate_1 = cv2.dilate(pie,kernel,iterations = 1)\n",
      "\n",
      "dilate_2 = cv2.dilate(pie,kernel,iterations = 2)\n",
      "\n",
      "dilate_3 = cv2.dilate(pie,kernel,iterations = 3)\n",
      "\n",
      "res = np.hstack((dilate_1,dilate_2,dilate_3))\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_79_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 开运算与闭运算\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 开：先腐蚀，再膨胀\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/dige.png')\n",
      "\n",
      "kernel = np.ones((5,5),np.uint8) \n",
      "\n",
      "opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)\n",
      "\n",
      "\n",
      "\n",
      "plt_show(opening)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_81_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 闭：先膨胀，再腐蚀\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/dige.png')\n",
      "\n",
      "kernel = np.ones((5,5),np.uint8)\n",
      "\n",
      "closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)\n",
      "\n",
      "plt_show(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_82_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 梯度运算\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 梯度=膨胀-腐蚀\n",
      "\n",
      "pie = cv2.imread('images_图像基本操作/pie.png')\n",
      "\n",
      "kernel = np.ones((7,7),np.uint8) \n",
      "\n",
      "dilate = cv2.dilate(pie,kernel,iterations = 5)\n",
      "\n",
      "erosion = cv2.erode(pie,kernel,iterations = 5)\n",
      "\n",
      "\n",
      "\n",
      "res = np.hstack((dilate,erosion))\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_84_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "gradient = cv2.morphologyEx(pie, cv2.MORPH_GRADIENT, kernel)\n",
      "\n",
      "plt_show(gradient)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_85_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 礼帽与黑帽\n",
      "\n",
      "- 礼帽 = 原始输入-开运算结果\n",
      "\n",
      "- 黑帽 = 闭运算-原始输入\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "#礼帽\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/dige.png')\n",
      "\n",
      "tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)\n",
      "\n",
      "plt_show(tophat)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_87_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "#黑帽\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/dige.png')\n",
      "\n",
      "blackhat  = cv2.morphologyEx(img,cv2.MORPH_BLACKHAT, kernel)\n",
      "\n",
      "plt_show(blackhat)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_88_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 图像梯度-Sobel算子\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/sobel_1.png)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/pie.png',cv2.IMREAD_GRAYSCALE)\n",
      "\n",
      "plt.imshow(img,cmap='gray')\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105d073a60>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_91_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "dst = cv2.Sobel(src, ddepth, dx, dy, ksize)\n",
      "\n",
      "- ddepth:图像的深度\n",
      "\n",
      "- dx和dy分别表示水平和竖直方向\n",
      "\n",
      "- ksize是Sobel算子的大小\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3) #算水平梯度\n",
      "\n",
      "plt.imshow(sobelx,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x110598472e0>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_93_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "白到黑是正数，黑到白就是负数了，所有的负数会被截断成0，所以要取绝对值\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)\n",
      "\n",
      "sobelx = cv2.convertScaleAbs(sobelx)  #转换成绝对值\n",
      "\n",
      "plt.imshow(sobelx,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105969e490>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_95_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)\n",
      "\n",
      "sobely = cv2.convertScaleAbs(sobely)  \n",
      "\n",
      "plt.imshow(sobely,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x110596e8820>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_96_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "分别计算x和y，再求和\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)\n",
      "\n",
      "plt.imshow(sobelxy,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x11059704c70>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_98_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "不建议直接计算\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)\n",
      "\n",
      "sobelxy = cv2.convertScaleAbs(sobelxy) \n",
      "\n",
      "plt.imshow(sobelxy,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x11057f64eb0>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_100_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/lena.jpg',cv2.IMREAD_GRAYSCALE)\n",
      "\n",
      "plt.imshow(img,cmap='gray')\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x110597fc400>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_101_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/lena.jpg',cv2.IMREAD_GRAYSCALE)\n",
      "\n",
      "sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)\n",
      "\n",
      "sobelx = cv2.convertScaleAbs(sobelx)\n",
      "\n",
      "sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)\n",
      "\n",
      "sobely = cv2.convertScaleAbs(sobely)\n",
      "\n",
      "sobelxy = cv2.addWeighted(sobelx,0.5,sobely,0.5,0)\n",
      "\n",
      "plt.imshow(sobelxy,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x110596679d0>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_102_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/lena.jpg',cv2.IMREAD_GRAYSCALE)\n",
      "\n",
      "sobelxy=cv2.Sobel(img,cv2.CV_64F,1,1,ksize=3)\n",
      "\n",
      "sobelxy = cv2.convertScaleAbs(sobelxy) \n",
      "\n",
      "plt.imshow(sobelxy,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105d0b3910>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_103_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 图像梯度-Scharr算子\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/scharr.png)\n",
      "\n",
      "\n",
      "\n",
      "### 图像梯度-laplacian算子\n",
      "\n",
      "对噪音敏感\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/l.png)\n",
      "\n",
      "\n",
      "\n",
      "### 不同算子的差异\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "#不同算子的差异\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/lena.jpg',cv2.IMREAD_GRAYSCALE)\n",
      "\n",
      "sobelx = cv2.Sobel(img,cv2.CV_64F,1,0,ksize=3)\n",
      "\n",
      "sobely = cv2.Sobel(img,cv2.CV_64F,0,1,ksize=3)\n",
      "\n",
      "sobelx = cv2.convertScaleAbs(sobelx)   \n",
      "\n",
      "sobely = cv2.convertScaleAbs(sobely)  \n",
      "\n",
      "sobelxy =  cv2.addWeighted(sobelx,0.5,sobely,0.5,0)  \n",
      "\n",
      "\n",
      "\n",
      "scharrx = cv2.Scharr(img,cv2.CV_64F,1,0)\n",
      "\n",
      "scharry = cv2.Scharr(img,cv2.CV_64F,0,1)\n",
      "\n",
      "scharrx = cv2.convertScaleAbs(scharrx)   \n",
      "\n",
      "scharry = cv2.convertScaleAbs(scharry)  \n",
      "\n",
      "scharrxy =  cv2.addWeighted(scharrx,0.5,scharry,0.5,0) \n",
      "\n",
      "\n",
      "\n",
      "laplacian = cv2.Laplacian(img,cv2.CV_64F)\n",
      "\n",
      "laplacian = cv2.convertScaleAbs(laplacian)   \n",
      "\n",
      "\n",
      "\n",
      "res = np.hstack((img,sobelxy,scharrxy,laplacian))\n",
      "\n",
      "plt.imshow(res,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x11059682490>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_109_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/lena.jpg',cv2.IMREAD_GRAYSCALE)\n",
      "\n",
      "plt.imshow(img,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105954ef40>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_110_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### Canny边缘检测\n",
      "\n",
      "- 1)        使用高斯滤波器，以平滑图像，滤除噪声。\n",
      "\n",
      "\n",
      "\n",
      "- 2)        计算图像中每个像素点的梯度强度和方向。\n",
      "\n",
      "\n",
      "\n",
      "- 3)        应用非极大值（Non-Maximum Suppression）抑制，以消除边缘检测带来的杂散响应。\n",
      "\n",
      "\n",
      "\n",
      "- 4)        应用双阈值（Double-Threshold）检测来确定真实的和潜在的边缘。\n",
      "\n",
      "\n",
      "\n",
      "- 5)        通过抑制孤立的弱边缘最终完成边缘检测。\n",
      "\n",
      "\n",
      "\n",
      "#### 1:高斯滤波器\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/canny_1.png)\n",
      "\n",
      "\n",
      "\n",
      "#### 2:梯度和方向\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/canny_2.png)\n",
      "\n",
      "\n",
      "\n",
      "#### 3：非极大值抑制\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/canny_3.png)\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/canny_6.png)\n",
      "\n",
      "\n",
      "\n",
      "#### 4：双阈值检测\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/canny_5.png)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img=cv2.imread(\"images_图像基本操作/lena.jpg\",cv2.IMREAD_GRAYSCALE)\n",
      "\n",
      "\n",
      "\n",
      "v1=cv2.Canny(img,80,150)\n",
      "\n",
      "v2=cv2.Canny(img,50,100)\n",
      "\n",
      "\n",
      "\n",
      "res = np.hstack((img,v1,v2))\n",
      "\n",
      "plt.imshow(res,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x11059669b80>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_121_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img=cv2.imread(\"images_图像基本操作/car.png\",cv2.IMREAD_GRAYSCALE)\n",
      "\n",
      "\n",
      "\n",
      "v1=cv2.Canny(img,120,250)\n",
      "\n",
      "v2=cv2.Canny(img,50,100)\n",
      "\n",
      "\n",
      "\n",
      "res = np.hstack((v1,v2))\n",
      "\n",
      "plt.imshow(res,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x110595e26a0>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_122_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 图像金字塔\n",
      "\n",
      "- 高斯金字塔\n",
      "\n",
      "- 拉普拉斯金字塔\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/Pyramid_1.png)\n",
      "\n",
      "\n",
      "\n",
      "#### 高斯金字塔：向下采样方法（缩小）\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/Pyramid_2.png)\n",
      "\n",
      "\n",
      "\n",
      "#### 高斯金字塔：向上采样方法（放大）\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/Pyramid_3.png)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img=cv2.imread(\"images_图像基本操作/AM.png\")\n",
      "\n",
      "plt_show(img)\n",
      "\n",
      "print (img.shape)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "    (442, 340, 3)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_129_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "up=cv2.pyrUp(img)\n",
      "\n",
      "plt_show(up)\n",
      "\n",
      "print (up.shape)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "    (884, 680, 3)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_130_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "down=cv2.pyrDown(img)\n",
      "\n",
      "plt_show(down)\n",
      "\n",
      "print (down.shape)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "    (221, 170, 3)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_131_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "up2=cv2.pyrUp(up)\n",
      "\n",
      "plt_show(up2)\n",
      "\n",
      "print (up2.shape)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "    (1768, 1360, 3)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_132_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "up=cv2.pyrUp(img)\n",
      "\n",
      "up_down=cv2.pyrDown(up)\n",
      "\n",
      "plt_show(up_down)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_133_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "plt_show(np.hstack((img,up_down)))\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_134_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "up=cv2.pyrUp(img)\n",
      "\n",
      "up_down=cv2.pyrDown(up)\n",
      "\n",
      "plt_show(img-up_down)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_135_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "#### 拉普拉斯金字塔\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/Pyramid_4.png)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "down=cv2.pyrDown(img)\n",
      "\n",
      "down_up=cv2.pyrUp(down)\n",
      "\n",
      "l_1=img-down_up\n",
      "\n",
      "plt_show(l_1)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_138_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 图像轮廓\n",
      "\n",
      "\n",
      "\n",
      "#### cv2.findContours(img,mode,method)\n",
      "\n",
      "mode:轮廓检索模式\n",
      "\n",
      "- RETR_EXTERNAL ：只检索最外面的轮廓；\n",
      "\n",
      "- RETR_LIST：检索所有的轮廓，并将其保存到一条链表当中；\n",
      "\n",
      "- RETR_CCOMP：检索所有的轮廓，并将他们组织为两层：顶层是各部分的外部边界，第二层是空洞的边界;\n",
      "\n",
      "- RETR_TREE：检索所有的轮廓，并重构嵌套轮廓的整个层次;(最常用)\n",
      "\n",
      "\n",
      "\n",
      "method:轮廓逼近方法\n",
      "\n",
      "- CHAIN_APPROX_NONE：以Freeman链码的方式输出轮廓，所有其他方法输出多边形（顶点的序列）。\n",
      "\n",
      "- CHAIN_APPROX_SIMPLE:压缩水平的、垂直的和斜的部分，也就是，函数只保留他们的终点部分。\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/chain.png)\n",
      "\n",
      "\n",
      "\n",
      "为了更高的准确率，使用二值图像。\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/car.png')\n",
      "\n",
      "gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  #转换成灰度图\n",
      "\n",
      "ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) #二值处理\n",
      "\n",
      "plt.imshow(thresh,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105d1e4730>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_143_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "'''\n",
      "\n",
      "contours中每个元素都是图像中的一个轮廓，用numpy中的ndarray表示\n",
      "\n",
      "每个轮廓contours[i]对应4个hierarchy元素hierarchy[i][0] ~hierarchy[i][3]，分别表示后一个轮廓、前一个轮廓、父轮廓、内嵌轮廓的索引编号，如果没有对应项，则该值为负数。\n",
      "\n",
      "'''\n",
      "\n",
      "contours, hierarchy= cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)\n",
      "\n",
      "print('len(contours) : {}'.format(len(contours)))\n",
      "\n",
      "print('hierarchy.shape : {}'.format(hierarchy.shape))\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "    len(contours) : 2579\n",
      "\n",
      "    hierarchy.shape : (1, 2579, 4)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "绘制轮廓\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "plt_show(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_146_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "#传入绘制图像，轮廓，轮廓索引，颜色模式，线条厚度\n",
      "\n",
      "# 注意需要copy,要不原图会变。。。\n",
      "\n",
      "draw_img = img.copy()\n",
      "\n",
      "res = cv2.drawContours(draw_img, contours, -1, (0, 0, 255), 2)\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_147_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "draw_img = img.copy()\n",
      "\n",
      "res = cv2.drawContours(draw_img, contours, 0, (0, 0, 255), 2)\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_148_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "#### 轮廓特征\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "cnt = contours[0]\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "#面积\n",
      "\n",
      "cv2.contourArea(cnt)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    1.5\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "#周长，True表示闭合的\n",
      "\n",
      "cv2.arcLength(cnt,True)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    5.414213538169861\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "#### 轮廓近似\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/contours3.png)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/contours2.png')\n",
      "\n",
      "\n",
      "\n",
      "gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n",
      "\n",
      "ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)\n",
      "\n",
      "contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)\n",
      "\n",
      "cnt = contours[0]\n",
      "\n",
      "\n",
      "\n",
      "draw_img = img.copy()\n",
      "\n",
      "res = cv2.drawContours(draw_img, [cnt], -1, (0, 0, 255), 2)\n",
      "\n",
      "\n",
      "\n",
      "plt_show(np.hstack([img,res]))\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_155_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "epsilon = 0.15*cv2.arcLength(cnt,True) \n",
      "\n",
      "approx = cv2.approxPolyDP(cnt,epsilon,True)\n",
      "\n",
      "\n",
      "\n",
      "draw_img = img.copy()\n",
      "\n",
      "res = cv2.drawContours(draw_img, [approx], -1, (0, 0, 255), 2)\n",
      "\n",
      "plt_show(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_156_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "边界矩形\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/contours.png')\n",
      "\n",
      "\n",
      "\n",
      "gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)\n",
      "\n",
      "ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)\n",
      "\n",
      "contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)\n",
      "\n",
      "cnt = contours[0]\n",
      "\n",
      "\n",
      "\n",
      "# 边界矩形\n",
      "\n",
      "x,y,w,h = cv2.boundingRect(cnt)\n",
      "\n",
      "img = cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)\n",
      "\n",
      "plt_show(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_158_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "area = cv2.contourArea(cnt)\n",
      "\n",
      "x, y, w, h = cv2.boundingRect(cnt)\n",
      "\n",
      "rect_area = w * h\n",
      "\n",
      "extent = float(area) / rect_area\n",
      "\n",
      "print ('轮廓面积与边界矩形比',extent)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "    轮廓面积与边界矩形比 0.5154317244724715\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "外接圆\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "(x,y),radius = cv2.minEnclosingCircle(cnt) \n",
      "\n",
      "center = (int(x),int(y)) \n",
      "\n",
      "radius = int(radius) \n",
      "\n",
      "img = cv2.circle(img,center,radius,(0,255,0),2)\n",
      "\n",
      "plt_show(img)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_161_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 傅里叶变换\n",
      "\n",
      "\n",
      "\n",
      "我们生活在时间的世界中，早上7:00起来吃早饭，8:00去挤地铁，9:00开始上班。。。以时间为参照就是时域分析。\n",
      "\n",
      "\n",
      "\n",
      "但是在频域中一切都是静止的！\n",
      "\n",
      "\n",
      "\n",
      "https://zhuanlan.zhihu.com/p/19763358\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 傅里叶变换的作用\n",
      "\n",
      "\n",
      "\n",
      "- 高频：变化剧烈的灰度分量，例如边界\n",
      "\n",
      "\n",
      "\n",
      "- 低频：变化缓慢的灰度分量，例如一片大海\n",
      "\n",
      "\n",
      "\n",
      "### 滤波\n",
      "\n",
      "\n",
      "\n",
      "- 低通滤波器：只保留低频，会使得图像模糊\n",
      "\n",
      "\n",
      "\n",
      "- 高通滤波器：只保留高频，会使得图像细节增强\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "- opencv中主要就是cv2.dft()和cv2.idft()，输入图像需要先转换成np.float32 格式。\n",
      "\n",
      "- 得到的结果中频率为0的部分会在左上角，通常要转换到中心位置，可以通过shift变换来实现。\n",
      "\n",
      "- cv2.dft()返回的结果是双通道的（实部，虚部），通常还需要转换成图像格式才能展示（0,255）。\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "import numpy as np\n",
      "\n",
      "import cv2\n",
      "\n",
      "from matplotlib import pyplot as plt\n",
      "\n",
      "\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/lena.jpg',0)\n",
      "\n",
      "img_float32 = np.float32(img)\n",
      "\n",
      "\n",
      "\n",
      "dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)\n",
      "\n",
      "dft_shift = np.fft.fftshift(dft)\n",
      "\n",
      "# 得到灰度图能表示的形式\n",
      "\n",
      "magnitude_spectrum = 20*np.log(cv2.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))\n",
      "\n",
      "\n",
      "\n",
      "plt.subplot(121),plt.imshow(img, cmap = 'gray')\n",
      "\n",
      "plt.title('Input Image'), plt.xticks([]), plt.yticks([])\n",
      "\n",
      "\n",
      "\n",
      "plt.subplot(122),plt.imshow(magnitude_spectrum, cmap = 'gray')\n",
      "\n",
      "plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])\n",
      "\n",
      "\n",
      "\n",
      "plt.show()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_166_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "import numpy as np\n",
      "\n",
      "import cv2\n",
      "\n",
      "from matplotlib import pyplot as plt\n",
      "\n",
      "\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/lena.jpg',0)\n",
      "\n",
      "\n",
      "\n",
      "img_float32 = np.float32(img)\n",
      "\n",
      "\n",
      "\n",
      "dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)\n",
      "\n",
      "dft_shift = np.fft.fftshift(dft)\n",
      "\n",
      "\n",
      "\n",
      "rows, cols = img.shape\n",
      "\n",
      "crow, ccol = int(rows/2) , int(cols/2)     # 中心位置\n",
      "\n",
      "\n",
      "\n",
      "# 低通滤波\n",
      "\n",
      "mask = np.zeros((rows, cols, 2), np.uint8)\n",
      "\n",
      "mask[crow-30:crow+30, ccol-30:ccol+30] = 1\n",
      "\n",
      "\n",
      "\n",
      "# IDFT\n",
      "\n",
      "fshift = dft_shift*mask\n",
      "\n",
      "f_ishift = np.fft.ifftshift(fshift)\n",
      "\n",
      "img_back = cv2.idft(f_ishift)\n",
      "\n",
      "img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])\n",
      "\n",
      "\n",
      "\n",
      "plt.subplot(121),plt.imshow(img, cmap = 'gray')\n",
      "\n",
      "plt.title('Input Image'), plt.xticks([]), plt.yticks([])\n",
      "\n",
      "plt.subplot(122),plt.imshow(img_back, cmap = 'gray')\n",
      "\n",
      "plt.title('Result'), plt.xticks([]), plt.yticks([])\n",
      "\n",
      "\n",
      "\n",
      "plt.show()                \n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_167_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/lena.jpg',0)\n",
      "\n",
      "\n",
      "\n",
      "img_float32 = np.float32(img)\n",
      "\n",
      "\n",
      "\n",
      "dft = cv2.dft(img_float32, flags = cv2.DFT_COMPLEX_OUTPUT)\n",
      "\n",
      "dft_shift = np.fft.fftshift(dft)\n",
      "\n",
      "\n",
      "\n",
      "rows, cols = img.shape\n",
      "\n",
      "crow, ccol = int(rows/2) , int(cols/2)     # 中心位置\n",
      "\n",
      "\n",
      "\n",
      "# 高通滤波\n",
      "\n",
      "mask = np.ones((rows, cols, 2), np.uint8)\n",
      "\n",
      "mask[crow-30:crow+30, ccol-30:ccol+30] = 0\n",
      "\n",
      "\n",
      "\n",
      "# IDFT\n",
      "\n",
      "fshift = dft_shift*mask\n",
      "\n",
      "f_ishift = np.fft.ifftshift(fshift)\n",
      "\n",
      "img_back = cv2.idft(f_ishift)\n",
      "\n",
      "img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])\n",
      "\n",
      "\n",
      "\n",
      "plt.subplot(121),plt.imshow(img, cmap = 'gray')\n",
      "\n",
      "plt.title('Input Image'), plt.xticks([]), plt.yticks([])\n",
      "\n",
      "plt.subplot(122),plt.imshow(img_back, cmap = 'gray')\n",
      "\n",
      "plt.title('Result'), plt.xticks([]), plt.yticks([])\n",
      "\n",
      "\n",
      "\n",
      "plt.show()    \n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_168_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "import cv2 #opencv读取的格式是BGR\n",
      "\n",
      "import numpy as np\n",
      "\n",
      "import matplotlib.pyplot as plt#Matplotlib是RGB\n",
      "\n",
      "%matplotlib inline \n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "### 直方图\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/hist_1.png)\n",
      "\n",
      "\n",
      "\n",
      "#### cv2.calcHist(images,channels,mask,histSize,ranges)\n",
      "\n",
      "\n",
      "\n",
      "- images: 原图像图像格式为 uint8 或 ﬂoat32。当传入函数时应 用中括号 [] 括来例如[img]\n",
      "\n",
      "- channels: 同样用中括号括来它会告函数我们统幅图 像的直方图。如果入图像是灰度图它的值就是 [0]如果是彩色图像 的传入的参数可以是 [0][1][2] 它们分别对应着 BGR。 \n",
      "\n",
      "- mask: 掩模图像。统计整幅图像的直方图就把它为 None。但是如 果你想统计图像某一部分的直方图的你就制作一个掩模图像并 使用它。\n",
      "\n",
      "- histSize:BIN 的数目。也应用中括号括来\n",
      "\n",
      "- ranges: 像素值范围常为 [0,256] \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/cat.jpg',0) #0表示灰度图\n",
      "\n",
      "hist = cv2.calcHist([img],[0],None,[256],[0,256])\n",
      "\n",
      "hist.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (256, 1)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "plt.hist(img.ravel(),256); \n",
      "\n",
      "plt.show()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_174_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/cat.jpg') \n",
      "\n",
      "color = ('b','g','r')\n",
      "\n",
      "for i,col in enumerate(color): \n",
      "\n",
      "    histr = cv2.calcHist([img],[i],None,[256],[0,256]) \n",
      "\n",
      "    plt.plot(histr,color = col) \n",
      "\n",
      "    plt.xlim([0,256]) \n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_175_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "mask操作\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 创建mask\n",
      "\n",
      "mask = np.zeros(img.shape[:2], np.uint8)\n",
      "\n",
      "print (mask.shape)\n",
      "\n",
      "mask[100:300, 100:400] = 255\n",
      "\n",
      "plt.imshow(mask,cmap=plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "    (414, 500)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105cf7d2e0>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_177_2.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/cat.jpg', 0)\n",
      "\n",
      "plt.imshow(img,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105d30ca30>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_178_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "masked_img = cv2.bitwise_and(img, img, mask=mask)#与操作\n",
      "\n",
      "plt.imshow(masked_img,plt.cm.gray)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105d161d90>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_179_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "hist_full = cv2.calcHist([img], [0], None, [256], [0, 256])\n",
      "\n",
      "hist_mask = cv2.calcHist([img], [0], mask, [256], [0, 256])\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "plt.subplot(221), plt.imshow(img, 'gray')\n",
      "\n",
      "plt.subplot(222), plt.imshow(mask, 'gray')\n",
      "\n",
      "plt.subplot(223), plt.imshow(masked_img, 'gray')\n",
      "\n",
      "plt.subplot(224), plt.plot(hist_full), plt.plot(hist_mask)\n",
      "\n",
      "plt.xlim([0, 256])\n",
      "\n",
      "plt.show()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_181_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "#### 直方图均衡化\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/hist_2.png)\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/hist_3.png)\n",
      "\n",
      "\n",
      "\n",
      "![title](images_图像基本操作/hist_4.png)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/clahe.jpg',0) #0表示灰度图 #clahe\n",
      "\n",
      "plt.hist(img.ravel(),256); \n",
      "\n",
      "plt.show()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_186_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "equ = cv2.equalizeHist(img) \n",
      "\n",
      "plt.hist(equ.ravel(),256)\n",
      "\n",
      "plt.show()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_187_0.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "res = np.hstack((img,equ))\n",
      "\n",
      "plt.imshow(res,cmap='gray')\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105cf4b7c0>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_188_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "#### 自适应直方图均衡化\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) \n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "res_clahe = clahe.apply(img)\n",
      "\n",
      "res = np.hstack((img,equ,res_clahe))\n",
      "\n",
      "plt.imshow(res,cmap='gray')\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105d263580>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_191_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 模板匹配\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "模板匹配和卷积原理很像，模板在原图像上从原点开始滑动，计算模板与（图像被模板覆盖的地方）的差别程度，这个差别程度的计算方法在opencv里有6种，然后将每次计算的结果放入一个矩阵里，作为结果输出。假如原图形是AxB大小，而模板是axb大小，则输出结果的矩阵是(A-a+1)x(B-b+1)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "# 模板匹配\n",
      "\n",
      "img = cv2.imread('images_图像基本操作/lena.jpg', 0)\n",
      "\n",
      "template = cv2.imread('images_图像基本操作/face.jpg', 0)\n",
      "\n",
      "h, w = template.shape[:2] \n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (263, 263)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "template.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (110, 85)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "- TM_SQDIFF：计算平方不同，计算出来的值越小，越相关        \n",
      "\n",
      "- TM_CCORR：计算相关性，计算出来的值越大，越相关\n",
      "\n",
      "- TM_CCOEFF：计算相关系数，计算出来的值越大，越相关\n",
      "\n",
      "- TM_SQDIFF_NORMED：计算归一化平方不同，计算出来的值越接近0，越相关\n",
      "\n",
      "- TM_CCORR_NORMED：计算归一化相关性，计算出来的值越接近1，越相关\n",
      "\n",
      "- TM_CCOEFF_NORMED：计算归一化相关系数，计算出来的值越接近1，越相关\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "公式：https://docs.opencv.org/3.3.1/df/dfb/group__imgproc__object.html#ga3a7850640f1fe1f58fe91a2d7583695d\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',\n",
      "\n",
      "           'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "res = cv2.matchTemplate(img, template, cv2.TM_SQDIFF)\n",
      "\n",
      "res.shape\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (154, 179)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "min_val\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    39168.0\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "max_val\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    74403584.0\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "min_loc\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (107, 89)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "max_loc\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    (159, 62)\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "for meth in methods:\n",
      "\n",
      "    img2 = img.copy()\n",
      "\n",
      "\n",
      "\n",
      "    # 匹配方法的真值\n",
      "\n",
      "    method = eval(meth)\n",
      "\n",
      "    print (meth)\n",
      "\n",
      "    res = cv2.matchTemplate(img, template, method)\n",
      "\n",
      "    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)\n",
      "\n",
      "\n",
      "\n",
      "    # 如果是平方差匹配TM_SQDIFF或归一化平方差匹配TM_SQDIFF_NORMED，取最小值\n",
      "\n",
      "    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:\n",
      "\n",
      "        top_left = min_loc\n",
      "\n",
      "    else:\n",
      "\n",
      "        top_left = max_loc\n",
      "\n",
      "    bottom_right = (top_left[0] + w, top_left[1] + h)\n",
      "\n",
      "\n",
      "\n",
      "    # 画矩形\n",
      "\n",
      "    cv2.rectangle(img2, top_left, bottom_right, 255, 2)\n",
      "\n",
      "\n",
      "\n",
      "    plt.subplot(121), plt.imshow(res, cmap='gray')\n",
      "\n",
      "    plt.xticks([]), plt.yticks([])  # 隐藏坐标轴\n",
      "\n",
      "    plt.subplot(122), plt.imshow(img2, cmap='gray')\n",
      "\n",
      "    plt.xticks([]), plt.yticks([])\n",
      "\n",
      "    plt.suptitle(meth)\n",
      "\n",
      "    plt.show()\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "    cv2.TM_CCOEFF\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_206_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    cv2.TM_CCOEFF_NORMED\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_206_3.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    cv2.TM_CCORR\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_206_5.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    cv2.TM_CCORR_NORMED\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_206_7.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    cv2.TM_SQDIFF\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_206_9.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    cv2.TM_SQDIFF_NORMED\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_206_11.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "### 匹配多个对象\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "```python\n",
      "\n",
      "img_rgb = cv2.imread('images_图像基本操作/mario.jpg')\n",
      "\n",
      "img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)\n",
      "\n",
      "template = cv2.imread('images_图像基本操作/mario_coin.jpg', 0)\n",
      "\n",
      "h, w = template.shape[:2]\n",
      "\n",
      "\n",
      "\n",
      "res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)\n",
      "\n",
      "threshold = 0.8\n",
      "\n",
      "# 取匹配程度大于%80的坐标\n",
      "\n",
      "loc = np.where(res >= threshold)\n",
      "\n",
      "for pt in zip(*loc[::-1]):  # *号表示可选参数\n",
      "\n",
      "    bottom_right = (pt[0] + w, pt[1] + h)\n",
      "\n",
      "    cv2.rectangle(img_rgb, pt, bottom_right, (0, 0, 255), 2)\n",
      "\n",
      "\n",
      "\n",
      "plt.imshow(img_rgb[:,:,[2,1,0]])\n",
      "\n",
      "```\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    <matplotlib.image.AxesImage at 0x1105d5fc490>\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "\n",
      "    \n",
      "\n",
      "![png](images_图像基本操作/output/output_208_1.png)\n",
      "\n",
      "    \n",
      "\n",
      "\n",
      "\n"
     ]
    }
   ],
   "source": [
    "for index,line in enumerate(lines):\n",
    "    print(line)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "a9c65cf7-dfd8-4e55-9f13-4be2a3798daa",
   "metadata": {},
   "outputs": [],
   "source": [
    "with open('图像基本操作2.md','w',encoding='utf-8') as f:\n",
    "    f.writelines(lines)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "007d944a-2d9e-429c-b7d2-a8120aec0820",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
